Kong 工具使用
Upstream 是什么
upstream 就是一个虚拟的服务,可以用于配置多个 target 用来实现负载均衡。
当我们部署集群时,一个单独的地址不足以满足我们的时候,我们可以使用 Kong 的 upstream 来进行设置。在 service 中的 host 可指定为 upstream 对象,upstream 添加多个 target 来实现负债均衡。
service 的 host 指的就是 upstram 的 name。
Service 是什么
服务实体,顾名思义,是您自己的上游服务的抽象,这个是官方文档的原话。其实理解起来就是就是我们自己定义的上游服务(upstraem),通过 Kong 匹配到相应的请求要转发的地方,Service 可以与下面的 Route 进行关联,一个 Service 可以有很多 Route,匹配到的 Route 就会转发到 Service 中。
Route 是什么
路由实体定义规则以匹配客户端的请求。每个 Route 与一个 Service 相关联,一个服务可能有多个与之关联的路由。与给定路由匹配的每个请求都将代理到其关联的 Service 上。可以配置的字段有:
- hosts
- paths
- methods
Service 和 Route 的组合(以及它们之间的关注点分离)提供了一种强大的路由机制,通过它可以在 Kong 中定义细粒度的入口点,从而使基础架构路由到不同上游服务。
对应关系
- Upstream : target -> 1:n
- Service : Upstream -> 1:1 or 1:0 (Service 可以直接指向具体的 Target,相当于不做负载均衡)
- Service : Route -> 1:n
路由匹配规则
现在让我们讨论 Kong 如何匹配针对路由的已配置 host,path 和 methods 属性(或字段)的请求。请注意,所有这三个字段都是可选的,但必须至少指定其中一个。
对于匹配路线的请求:
- 请求必须包含所有已配置的字段
- 请求中的字段值必须至少与其中一个配置值匹配(当字段配置接收一个或多个值时,请求只需要其中一个值被视为匹配)
这里思考一个问题,Kong route 中的 host 的作用是什么?有什么意义?哪些场景会用到设置多个 host 呢?
这是官方的解释:
Routing a request based on its Host header is the most straightforward way to proxy traffic through Kong, as this is the intended usage of the HTTP Host header. Kong makes it easy to do so via the hosts field of the API entity.
显然官方对 host 的说明,没有回答上面的问题,下面看下网络上对 host 的解释: 我们知道 HTTP 请求头信息里面会带有一个 Host 字段,很多人不是很清楚这个字段具体的作用或者用法,包括我被很多人问过也曾经有些迷茫,这里具体扫盲下。
Host 是 HTTP 1.1 协议中新增的一个请求头,主要用来实现虚拟主机技术。我们知道一个 IP 地址可以对应多个域名,比如假设我有这么几个域名 www.baidu.com,www.taobao.com 和 www.jd.com 然后在域名提供商那通过 A 记录或者 CNAME 记录的方式最终都和我的虚拟机服务器 IP:111.111.111.111 关联起来,那么我通过任何一个域名去访问最终解析到的都是 IP:111.111.111.111。
但是还是没有提到 Host 的概念,其实可以这样看,我们的那台虚拟机 111.111.111.111 上面其实是可以放很多很多网站的(不然如果只能放一个网站的话就太不合理了,虚拟机那么多资源都浪费了),我们可以把 www.baidu.com,www.taobao.com 和 www.jd.com 这些网站假设都部署在那台虚拟机上面,但是这样会有一个问题,我们每次访问这些域名其实都是解析到服务器 IP:111.111.111.111,我怎么来区分每次根据域名显示出不同的网站的内容呢,其实这就要用到请求头中 Host 的概念了,每个 Host 可以看做是我在服务器 111.111.111.111 上面的一个站点,每次我用那些域名访问的时候都是会解析同一个虚拟机没错,但是我通过不同的 Host 可以区分出我是访问这个虚拟机上的哪个站点。
我们再来看几个例子就彻底明白了。考虑如下配置的路由:
{
"hosts": ["example.com", "test-service.com"],
"paths": ["/header", "/test"],
"methods": ["GET"]
}
下面我们假设请求时不带 Host:
curl -v -H "Host: ''" -i http://localhost:8000/users/1
注意观察请求头,* Connected to localhost (127.0.0.1) port 8000 (#0);客户端和 Kong 建立了 tcp 连接,但是 host 是空的,所以 Kong 匹配不到上面的 route。
让我们看下设置了正确 Host 的请求:
curl -v -H "Host: example.com" -i http://localhost:8000/users/1
这次 Kong 匹配到了 route,所以拿到了数据。